#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>

// 测试系统调用的接口
void testOS1()
{
    int fd = open("log.txt", O_WRONLY | O_CREAT | O_TRUNC, 0666);
    if (fd < 0)
    {
        perror("open fail\n");
        exit(1);
    }
    close(fd);
}

void testOS2()
{
    int fd = open("log.txt", O_WRONLY | O_CREAT | O_TRUNC, 0666);
    if (fd < 0)
    {
        perror("open fail\n");
        exit(1);
    }
    printf("fd : %d\n", fd);
    close(fd);
}

void testOS3()
{
    int fd1 = open("log.txt", O_WRONLY | O_CREAT | O_TRUNC, 0666);
    int fd2 = open("log.txt", O_WRONLY | O_CREAT | O_TRUNC, 0666);
    int fd3 = open("log.txt", O_WRONLY | O_CREAT | O_TRUNC, 0666);
    printf("fd : %d\n", fd1);
    printf("fd : %d\n", fd2);
    printf("fd : %d\n", fd3);
    close(fd1);
    close(fd2);
    close(fd3);
}

void testOS4()
{
    FILE *fp = fopen("homework.txt", "w+");
    if (fp == NULL)
    {
        perror("fopen fail!\n");
        exit(1);
    }
    fprintf(fp, "%s", "linux so easy!\n");
    char str1[20], str2[20], str3[20], str4[20];
    rewind(fp);
    fscanf(fp, "%s %s %s %s", str1, str2, str3, str4);
    printf("%s %s %s %s", str1, str2, str3, str4);
    fclose(fp);
}

// 测试文件的各种接口
void testCfile1()
{
    // 以w的方式打开文件
    FILE *fp = fopen("log.txt", "w");
    if (fp == NULL)
    {
        perror("fopen fail\n");
        exit(1);
    }
    fclose(fp);
}

void testCfile2()
{
    // 以a的方式打开文件
    FILE *fp = fopen("log.txt", "a");
    if (fp == NULL)
    {
        perror("fopen fail\n");
        exit(1);
    }
    fclose(fp);
}

void testCfile3()
{
    // 向文件中写入信息
    FILE *fp = fopen("log.txt", "a");
    const char *msg = "hello linux\n";
    if (fp == NULL)
    {
        perror("fopen fail\n");
        exit(1);
    }
    fputs(msg, fp);
    fclose(fp);
}

// fd的分配原则
void testfd0()
{
    char buffer[1024];
    ssize_t s = read(0, buffer, 1024);
    buffer[s - 1] = 0;
    printf("%s\n", buffer);
}

void testfd1()
{
    int fd = open("log.txt", O_CREAT | O_WRONLY | O_TRUNC, 0666);
    printf("fd -> %d\n", fd);
    close(fd);
}

void testfd2()
{
    close(0);
    int fd = open("log.txt", O_CREAT | O_WRONLY | O_TRUNC, 0666);
    printf("fd -> %d\n", fd);
    close(fd);
}

// 重定向
void redir1()
{
    close(1);
    int fd = open("log.txt", O_CREAT | O_WRONLY | O_TRUNC, 0666);
    if (fd < 0)
    {
        perror("open fail\n");
        exit(1);
    }
    printf("fd-> %d\n", fd);
    printf("stdout->fd: %d\n", stdout->_fileno);
    fflush(stdout);
    close(fd);
}

void redir2()
{
    int fd = open("log.txt", O_CREAT | O_WRONLY | O_APPEND, 0666);
    if (fd < 0)
    {
        perror("open fail\n");
        exit(1);
    }
    dup2(fd, 1);
    printf("fd-> %d\n", fd);
    printf("stdout->fd: %d\n", stdout->_fileno);
    fflush(stdout);
    close(fd);
}

void teststderr()
{
    printf("this is normal message\n");
    perror("this is error message\n");
}

void home()
{
    int fd = open("homework.txt", O_CREAT | O_RDWR | O_TRUNC, 0666);
    const char *str = "i like linux!";
    write(fd, str, strlen(str));
    lseek(fd, 0, SEEK_SET);
    char buffer[1024];
    ssize_t s = read(fd, buffer, 1024);
    if (s == -1)
    {
        perror("read fail\n");
        exit(1);
    }
    buffer[s - 1] = 0;
    printf("%s\n", buffer);
    printf("%d\n", fd);
}

int main()
{
    home();
    return 0;
}